package Thread;

import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 邓大帅
 * Date: 2024-01-24
 * Time: 18:53
 */
//所谓内存可见性，就是在多线程环境下，编译器对代码进行优化，对于结果产生了误判，从而引发了bug
//指令重排序也是一种编译器优化，在某些场景下可能也会导致bug，同样可以用volatile避免编译器优化
public class ThreadDemo6 {
//    volatile与原子性无关 synchronized保证原子性，volatile保证内存可见性以及禁止指令重排序  synchronized能否保证内存可见性存在争议
//    编译器不会对volatile修饰的变量进行优化
//    volatile的作用就是禁止编译器优化
    volatile public static int flag = 0;

    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
//            这里如果flag在声明时未被volatile关键字修饰，由于这个循环，大部分时间是从内存读flag的值占运行时间的大头
//            对此，编译器会进行优化，只读取一次flag的值，后续不再读入，这导致当其他线程修改flag的值来终止循环时做不到，这个循环仍会执行
//            如果flag一开始在声明时由volatile修饰，编译器就不会对flag进行优化，也就不会产生上述问题
            while (flag == 0) {

            }
            System.out.println("循环结束");
        });
        Thread thread1 = new Thread(() -> {
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入一个数字：");
            flag = scanner.nextInt();
        });
        thread.start();
        thread1.start();
    }
}
